From 790d8e324b7e7af6e81b6a98af004c4cc0797109 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 29 Jun 2011 15:23:06 +0200 Subject: [PATCH] a11y: Redo notebook page management Previously, the code tried to track the indexes of the pages and keep them up to date in a list and tracking the index in the GtkNotebookPage. Now, we store the widget we are tracking in the GailNotebookPage and keep a hash table of widget=>GailNotebookPage in the GailNotebook. This frees us from the burden of tracking page changes. --- gtk/a11y/gailnotebook.c | 161 +++++------------------------------- gtk/a11y/gailnotebook.h | 5 +- gtk/a11y/gailnotebookpage.c | 39 +++------ gtk/a11y/gailnotebookpage.h | 9 +- 4 files changed, 37 insertions(+), 177 deletions(-) diff --git a/gtk/a11y/gailnotebook.c b/gtk/a11y/gailnotebook.c index 9997547e01..f00283abf2 100644 --- a/gtk/a11y/gailnotebook.c +++ b/gtk/a11y/gailnotebook.c @@ -43,20 +43,9 @@ static AtkObject* gail_notebook_ref_selection (AtkSelection *selection static gint gail_notebook_get_selection_count (AtkSelection *selection); static gboolean gail_notebook_is_child_selected (AtkSelection *selection, gint i); -static AtkObject* find_child_in_list (GList *list, - gint index); -static void check_cache (GailNotebook *gail_notebook, - GtkNotebook *notebook); -static void reset_cache (GailNotebook *gail_notebook, - gint index); static void create_notebook_page_accessible (GailNotebook *gail_notebook, GtkNotebook *notebook, - gint index, - gboolean insert_before, - GList *list); -static void gail_notebook_child_parent_set (GtkWidget *widget, - GtkWidget *old_parent, - gpointer data); + GtkWidget *child); static gboolean gail_notebook_focus_cb (GtkWidget *widget, GtkDirectionType type); static gboolean gail_notebook_check_focus_tab (gpointer data); @@ -91,10 +80,12 @@ gail_notebook_class_init (GailNotebookClass *klass) static void gail_notebook_init (GailNotebook *notebook) { - notebook->page_cache = NULL; + notebook->pages = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + g_object_unref); notebook->selected_page = -1; notebook->focus_tab_page = -1; - notebook->remove_index = -1; notebook->idle_focus_id = 0; } @@ -115,15 +106,13 @@ gail_notebook_ref_child (AtkObject *obj, return NULL; gail_notebook = GAIL_NOTEBOOK (obj); - gtk_notebook = GTK_NOTEBOOK (widget); - if (gail_notebook->page_count < gtk_notebook_get_n_pages (gtk_notebook)) - check_cache (gail_notebook, gtk_notebook); - - accessible = find_child_in_list (gail_notebook->page_cache, i); + accessible = g_hash_table_lookup (gail_notebook->pages, + gtk_notebook_get_nth_page (gtk_notebook, i)); + /* can return NULL when i >= n_children */ - if (accessible != NULL) + if (accessible) g_object_ref (accessible); return accessible; @@ -140,8 +129,7 @@ gail_notebook_page_added (GtkNotebook *gtk_notebook, atk_obj = gtk_widget_get_accessible (GTK_WIDGET (gtk_notebook)); notebook = GAIL_NOTEBOOK (atk_obj); - create_notebook_page_accessible (notebook, gtk_notebook, page_num, FALSE, NULL); - notebook->page_count++; + create_notebook_page_accessible (notebook, gtk_notebook, child); } static void @@ -152,24 +140,18 @@ gail_notebook_page_removed (GtkNotebook *notebook, { GailNotebook *gail_notebook; AtkObject *obj; - gint index; gail_notebook = GAIL_NOTEBOOK (gtk_widget_get_accessible (GTK_WIDGET (notebook))); - index = gail_notebook->remove_index; - gail_notebook->remove_index = -1; - obj = find_child_in_list (gail_notebook->page_cache, index); + obj = g_hash_table_lookup (gail_notebook->pages, widget); g_return_if_fail (obj); - gail_notebook->page_cache = g_list_remove (gail_notebook->page_cache, obj); - gail_notebook->page_count -= 1; - reset_cache (gail_notebook, index); g_signal_emit_by_name (gail_notebook, "children_changed::remove", page_num, obj, NULL); gail_notebook_page_invalidate (GAIL_NOTEBOOK_PAGE (obj)); - g_object_unref (obj); + g_hash_table_remove (gail_notebook->pages, widget); } static void @@ -186,9 +168,10 @@ gail_notebook_real_initialize (AtkObject *obj, gtk_notebook = GTK_NOTEBOOK (data); for (i = 0; i < gtk_notebook_get_n_pages (gtk_notebook); i++) { - create_notebook_page_accessible (notebook, gtk_notebook, i, FALSE, NULL); + create_notebook_page_accessible (notebook, + gtk_notebook, + gtk_notebook_get_nth_page (gtk_notebook, i)); } - notebook->page_count = i; notebook->selected_page = gtk_notebook_get_current_page (gtk_notebook); g_signal_connect (gtk_notebook, @@ -231,8 +214,6 @@ gail_notebook_real_notify_gtk (GObject *obj, gail_notebook = GAIL_NOTEBOOK (atk_obj); gtk_notebook = GTK_NOTEBOOK (widget); - if (gail_notebook->page_count < gtk_notebook_get_n_pages (gtk_notebook)) - check_cache (gail_notebook, gtk_notebook); /* * Notify SELECTED state change for old and new page */ @@ -290,22 +271,8 @@ static void gail_notebook_finalize (GObject *object) { GailNotebook *notebook = GAIL_NOTEBOOK (object); - GList *list; - - /* - * Get rid of the GailNotebookPage objects which we have cached. - */ - list = notebook->page_cache; - if (list != NULL) - { - while (list) - { - g_object_unref (list->data); - list = list->next; - } - } - g_list_free (notebook->page_cache); + g_hash_table_destroy (notebook->pages); if (notebook->idle_focus_id) g_source_remove (notebook->idle_focus_id); @@ -428,103 +395,17 @@ gail_notebook_is_child_selected (AtkSelection *selection, return FALSE; } -static AtkObject* -find_child_in_list (GList *list, - gint index) -{ - AtkObject *obj = NULL; - - while (list) - { - if (GAIL_NOTEBOOK_PAGE (list->data)->index == index) - { - obj = ATK_OBJECT (list->data); - break; - } - list = list->next; - } - return obj; -} - -static void -check_cache (GailNotebook *gail_notebook, - GtkNotebook *notebook) -{ - GList *gtk_list; - GList *gail_list; - gint i; - - gtk_list = gtk_container_get_children (GTK_CONTAINER (notebook)); - gail_list = gail_notebook->page_cache; - - i = 0; - while (gtk_list) - { - if (!gail_list) - { - create_notebook_page_accessible (gail_notebook, notebook, i, FALSE, NULL); - } - else if (GAIL_NOTEBOOK_PAGE (gail_list->data)->page != gtk_list->data) - { - create_notebook_page_accessible (gail_notebook, notebook, i, TRUE, gail_list); - } - else - { - gail_list = gail_list->next; - } - i++; - gtk_list = gtk_list->next; - } - g_list_free (gtk_list); - - gail_notebook->page_count = i; -} - -static void -reset_cache (GailNotebook *gail_notebook, - gint index) -{ - GList *l; - - for (l = gail_notebook->page_cache; l; l = l->next) - { - if (GAIL_NOTEBOOK_PAGE (l->data)->index > index) - GAIL_NOTEBOOK_PAGE (l->data)->index -= 1; - } -} - static void create_notebook_page_accessible (GailNotebook *gail_notebook, GtkNotebook *notebook, - gint index, - gboolean insert_before, - GList *list) + GtkWidget *child) { AtkObject *obj; - obj = gail_notebook_page_new (notebook, index); - g_object_ref (obj); - if (insert_before) - gail_notebook->page_cache = g_list_insert_before (gail_notebook->page_cache, list, obj); - else - gail_notebook->page_cache = g_list_append (gail_notebook->page_cache, obj); - g_signal_connect (gtk_notebook_get_nth_page (notebook, index), - "parent_set", - G_CALLBACK (gail_notebook_child_parent_set), - obj); -} - -static void -gail_notebook_child_parent_set (GtkWidget *widget, - GtkWidget *old_parent, - gpointer data) -{ - GailNotebook *gail_notebook; - - if (!old_parent) - return; - gail_notebook = GAIL_NOTEBOOK (gtk_widget_get_accessible (old_parent)); - gail_notebook->remove_index = GAIL_NOTEBOOK_PAGE (data)->index; + obj = gail_notebook_page_new (notebook, child); + g_hash_table_insert (gail_notebook->pages, + child, + obj); } static gboolean diff --git a/gtk/a11y/gailnotebook.h b/gtk/a11y/gailnotebook.h index fd16a3b9a9..a22c5f4f24 100644 --- a/gtk/a11y/gailnotebook.h +++ b/gtk/a11y/gailnotebook.h @@ -44,13 +44,10 @@ struct _GailNotebook * If the page is found in the list then a new page does not * need to be created */ - GList* page_cache; + GHashTable * pages; gint selected_page; gint focus_tab_page; - gint page_count; guint idle_focus_id; - - gint remove_index; }; GType gail_notebook_get_type (void); diff --git a/gtk/a11y/gailnotebookpage.c b/gtk/a11y/gailnotebookpage.c index 13b3e56969..6b31280449 100644 --- a/gtk/a11y/gailnotebookpage.c +++ b/gtk/a11y/gailnotebookpage.c @@ -156,7 +156,11 @@ notify_child_added (gpointer data) { atk_parent = gtk_widget_get_accessible (GTK_WIDGET (page->notebook)); atk_object_set_parent (atk_object, atk_parent); - g_signal_emit_by_name (atk_parent, "children_changed::add", page->index, atk_object, NULL); + g_signal_emit_by_name (atk_parent, + "children_changed::add", + gtk_notebook_page_num (page->notebook, page->child), + atk_object, + NULL); } return FALSE; @@ -164,30 +168,20 @@ notify_child_added (gpointer data) AtkObject* gail_notebook_page_new (GtkNotebook *notebook, - gint pagenum) + GtkWidget *child) { GObject *object; AtkObject *atk_object; GailNotebookPage *page; - GtkWidget *child; GtkWidget *label; - GtkWidget *widget_page; g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL); - child = gtk_notebook_get_nth_page (notebook, pagenum); - - if (!child) - return NULL; - object = g_object_new (GAIL_TYPE_NOTEBOOK_PAGE, NULL); - g_return_val_if_fail (object != NULL, NULL); page = GAIL_NOTEBOOK_PAGE (object); page->notebook = notebook; - page->index = pagenum; - widget_page = gtk_notebook_get_nth_page (notebook, pagenum); - page->page = widget_page; + page->child = child; page->textutil = NULL; atk_object = ATK_OBJECT (page); @@ -223,6 +217,7 @@ gail_notebook_page_invalidate (GailNotebookPage *page) TRUE); atk_object_set_parent (ATK_OBJECT (page), NULL); page->notebook = NULL; + page->child = NULL; } static void @@ -349,7 +344,6 @@ static AtkObject* gail_notebook_page_ref_child (AtkObject *accessible, gint i) { - GtkWidget *child; AtkObject *child_obj; GailNotebookPage *page = NULL; @@ -361,11 +355,7 @@ gail_notebook_page_ref_child (AtkObject *accessible, if (!page->notebook) return NULL; - child = gtk_notebook_get_nth_page (page->notebook, page->index); - if (!GTK_IS_WIDGET (child)) - return NULL; - - child_obj = gtk_widget_get_accessible (child); + child_obj = gtk_widget_get_accessible (page->child); g_object_ref (child_obj); return child_obj; } @@ -375,10 +365,11 @@ gail_notebook_page_get_index_in_parent (AtkObject *accessible) { GailNotebookPage *page; - g_return_val_if_fail (GAIL_IS_NOTEBOOK_PAGE (accessible), -1); page = GAIL_NOTEBOOK_PAGE (accessible); + if (!page->notebook || !page->child) + return -1; - return page->index; + return gtk_notebook_page_num (page->notebook, page->child); } static AtkStateSet* @@ -794,11 +785,7 @@ get_label_from_notebook_page (GailNotebookPage *page) if (!gtk_notebook_get_show_tabs (notebook)) return NULL; - child = gtk_notebook_get_nth_page (notebook, page->index); - if (child == NULL) return NULL; - g_return_val_if_fail (GTK_IS_WIDGET (child), NULL); - - child = gtk_notebook_get_tab_label (notebook, child); + child = gtk_notebook_get_tab_label (notebook, page->child); if (GTK_IS_LABEL (child)) return child; diff --git a/gtk/a11y/gailnotebookpage.h b/gtk/a11y/gailnotebookpage.h index 78aaca4164..5f68b5f1af 100644 --- a/gtk/a11y/gailnotebookpage.h +++ b/gtk/a11y/gailnotebookpage.h @@ -40,13 +40,8 @@ struct _GailNotebookPage AtkObject parent; GtkNotebook *notebook; -#ifndef GTK_DISABLE_DEPRECATED - GtkNotebookPage *page; -#else - gpointer page; -#endif - gint index; + GtkWidget *child; guint notify_child_added_id; GailTextUtil *textutil; @@ -59,7 +54,7 @@ struct _GailNotebookPageClass AtkObjectClass parent_class; }; -AtkObject *gail_notebook_page_new(GtkNotebook *notebook, gint pagenum); +AtkObject *gail_notebook_page_new(GtkNotebook *notebook, GtkWidget *child); void gail_notebook_page_invalidate (GailNotebookPage *page); -- 2.30.2